home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS02.ADF / Emacs / search.c < prev    next >
C/C++ Source or Header  |  1989-05-30  |  6KB  |  245 lines

  1. /* search.c */
  2.  
  3. /*
  4.  * The functions in this file implement commands that search in the forward
  5.  * and backward directions. There are no special characters in the search
  6.  * strings. Probably should have a regular expression search, or something
  7.  * like that.
  8.  *
  9.  * REVISION HISTORY:
  10.  *
  11.  * ?    Steve Wilhite, 1-Dec-85
  12.  *      - massive cleanup on code.
  13.  */
  14.  
  15. #include        <stdio.h>
  16. #include        "ed.h"
  17.  
  18. /*
  19.  * Search forward. Get a search string from the user, and search, beginning at
  20.  * ".", for the string. If found, reset the "." to be just after the match
  21.  * string, and [perhaps] repaint the display. Bound to "C-S".
  22.  */
  23. forwsearch(f, n)
  24.     {
  25.     register LINE *clp;
  26.     register int cbo;
  27.     register LINE*tlp;
  28.     register int tbo;
  29.     register int c;
  30.     register char *pp;
  31.     register int s;
  32.  
  33.     if ((s = readpattern("Search")) != TRUE)
  34.         return (s);
  35.  
  36.     clp = curwp->w_dotp;
  37.     cbo = curwp->w_doto;
  38.  
  39.     while (clp != curbp->b_linep)
  40.         {
  41.         if (cbo == llength(clp))
  42.             {
  43.             clp = lforw(clp);
  44.             cbo = 0;
  45.             c = '\n';
  46.             }
  47.         else
  48.             c = lgetc(clp, cbo++);
  49.  
  50.         if (eq(c, pat[0]) != FALSE)
  51.             {
  52.             tlp = clp;
  53.             tbo = cbo;
  54.             pp  = &pat[1];
  55.  
  56.             while (*pp != 0)
  57.                 {
  58.                 if (tlp == curbp->b_linep)
  59.                     goto fail;
  60.  
  61.                 if (tbo == llength(tlp))
  62.                     {
  63.                     tlp = lforw(tlp);
  64.                     tbo = 0;
  65.                     c = '\n';
  66.                     }
  67.                 else
  68.                     c = lgetc(tlp, tbo++);
  69.  
  70.                 if (eq(c, *pp++) == FALSE)
  71.                     goto fail;
  72.                 }
  73.  
  74.             curwp->w_dotp  = tlp;
  75.             curwp->w_doto  = tbo;
  76.             curwp->w_flag |= WFMOVE;
  77.             return (TRUE);
  78.             }
  79. fail:;
  80.         }
  81.  
  82.     mlwrite("Not found");
  83.     return (FALSE);
  84.     }
  85.  
  86. /*
  87.  * Reverse search. Get a search string from the user, and search, starting at
  88.  * "." and proceeding toward the front of the buffer. If found "." is left
  89.  * pointing at the first character of the pattern [the last character that was
  90.  j matched]. Bound to "C-R".
  91.  */
  92. backsearch(f, n)
  93.     {
  94.     register LINE *clp;
  95.     register int cbo;
  96.     register LINE *tlp;
  97.     register int tbo;
  98.     register int c;
  99.     register char *epp;
  100.     register char *pp;
  101.     register int s;
  102.  
  103.     if ((s = readpattern("Reverse search")) != TRUE)
  104.         return (s);
  105.  
  106.     for (epp = &pat[0]; epp[1] != 0; ++epp)
  107.         ;
  108.  
  109.     clp = curwp->w_dotp;
  110.     cbo = curwp->w_doto;
  111.  
  112.     for (;;)
  113.         {
  114.         if (cbo == 0)
  115.             {
  116.             clp = lback(clp);
  117.  
  118.             if (clp == curbp->b_linep)
  119.                 {
  120.                 mlwrite("Not found");
  121.                 return (FALSE);
  122.                 }
  123.  
  124.             cbo = llength(clp)+1;
  125.             }
  126.  
  127.         if (--cbo == llength(clp))
  128.             c = '\n';
  129.         else
  130.             c = lgetc(clp, cbo);
  131.  
  132.         if (eq(c, *epp) != FALSE)
  133.             {
  134.             tlp = clp;
  135.             tbo = cbo;
  136.             pp  = epp;
  137.  
  138.             while (pp != &pat[0])
  139.                 {
  140.                 if (tbo == 0)
  141.                     {
  142.                     tlp = lback(tlp);
  143.                     if (tlp == curbp->b_linep)
  144.                         goto fail;
  145.  
  146.                     tbo = llength(tlp)+1;
  147.                     }
  148.  
  149.                 if (--tbo == llength(tlp))
  150.                     c = '\n';
  151.                 else
  152.                     c = lgetc(tlp, tbo);
  153.  
  154.                 if (eq(c, *--pp) == FALSE)
  155.                     goto fail;
  156.                 }
  157.  
  158.             curwp->w_dotp  = tlp;
  159.             curwp->w_doto  = tbo;
  160.             curwp->w_flag |= WFMOVE;
  161.             return (TRUE);
  162.             }
  163. fail:;
  164.         }
  165.     }
  166.  
  167. /*
  168.  * Compare two characters. The "bc" comes from the buffer. It has it's case
  169.  * folded out. The "pc" is from the pattern.
  170.  */
  171. eq(bc, pc)
  172.     int bc;
  173.     int pc;
  174.     {
  175.     if (bc>='a' && bc<='z')
  176.         bc -= 0x20;
  177.  
  178.     if (pc>='a' && pc<='z')
  179.         pc -= 0x20;
  180.  
  181.     if (bc == pc)
  182.         return (TRUE);
  183.  
  184.     return (FALSE);
  185.     }
  186.  
  187. /*
  188.  * Read a pattern. Stash it in the external variable "pat". The "pat" is not
  189.  * updated if the user types in an empty line. If the user typed an empty line,
  190.  * and there is no old pattern, it is an error. Display the old pattern, in the
  191.  * style of Jeff Lomicka. There is some do-it-yourself control expansion.
  192.  */
  193. readpattern(prompt)
  194.     char *prompt;
  195.     {
  196.     register char *cp1;
  197.     register char *cp2;
  198.     register int c;
  199.     register int s;
  200.     char tpat[NPAT+20];
  201.  
  202.     cp1 = &tpat[0];                     /* Copy prompt */
  203.     cp2 = prompt;
  204.  
  205.     while ((c = *cp2++) != '\0')
  206.         *cp1++ = c;
  207.  
  208.     if (pat[0] != '\0')                 /* Old pattern */
  209.         {
  210.         *cp1++ = ' ';
  211.         *cp1++ = '[';
  212.         cp2 = &pat[0];
  213.  
  214.         while ((c = *cp2++) != 0)
  215.             {
  216.             if (cp1 < &tpat[NPAT+20-6]) /* "??]: \0" */
  217.                 {
  218.                 if (c<0x20 || c==0x7F) {
  219.                     *cp1++ = '^';
  220.                     c ^= 0x40;
  221.                     }
  222.                 else if (c == '%')      /* Map "%" to */
  223.                     *cp1++ = c;         /* "%%". */
  224.  
  225.                 *cp1++ = c;
  226.                 }
  227.             }
  228.  
  229.         *cp1++ = ']';
  230.         }
  231.  
  232.     *cp1++ = ':';                       /* Finish prompt */
  233.     *cp1++ = ' ';
  234.     *cp1++ = '\0';
  235.     s = mlreply(tpat, tpat, NPAT);      /* Read pattern */
  236.  
  237.     if (s == TRUE)                      /* Specified */
  238.         strcpy(pat, tpat);
  239.     else if (s == FALSE && pat[0] != 0)         /* CR, but old one */
  240.         s = TRUE;
  241.  
  242.     return (s);
  243.     }
  244.  
  245.